"""API接口模块.

本模块提供系统的REST API接口:

1. 健康检查接口
   - 系统状态检查
   - 数据库连接检查
   - 依赖服务检查

2. 商家评分接口
   - 获取商家评分
   - 查询评分历史
   - 批量更新评分

3. 用户评分接口
   - 获取用户评分
   - 查询评分历史
   - 信用恢复处理
   - 批量更新评分

4. 风险控制接口
   - 交易风险评估
   - 异常检测
   - 风险预警
"""

from datetime import datetime
from typing import Dict, List, Optional

from fastapi import FastAPI, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

from ..data.db_manager import DatabaseManager
from ..models.risk_model import RiskModel
from ..scoring.credit_scorer import CreditScorer
from ..scoring.user_credit_scorer import UserCreditScorer
from ..utils.logger import logger
from ..utils.system import SystemMonitor

# 创建FastAPI应用实例
app = FastAPI(
    title="信用风险控制系统API",
    description="提供商家和用户信用评分、风险控制等功能的REST API接口",
    version="0.1.0"
)

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)

# 初始化组件
db_manager = DatabaseManager()
system_monitor = SystemMonitor()
merchant_scorer = CreditScorer()
user_scorer = UserCreditScorer()
risk_model = RiskModel()


# 请求/响应模型
class HealthResponse(BaseModel):
    """健康检查响应模型."""
    status: str
    database: bool
    system_info: Dict
    timestamp: str


class ScoreResponse(BaseModel):
    """评分响应模型."""
    score: float
    dimension_scores: Dict[str, float]
    credit_level: str
    privileges: List[str]
    timestamp: str


class RiskResponse(BaseModel):
    """风险评估响应模型."""
    risk_level: str
    risk_score: float
    risk_factors: Dict[str, float]
    timestamp: str


class RecoveryEligibilityResponse(BaseModel):
    """信用恢复资格响应模型."""
    is_eligible: bool
    status: str
    timestamp: str


class RecoveryProcessResponse(BaseModel):
    """信用恢复处理响应模型."""
    success: bool
    message: str
    new_level: str
    timestamp: str


class BatchUpdateResponse(BaseModel):
    """批量更新响应模型."""
    success: bool
    processed_count: int
    timestamp: str


@app.get("/")
async def root():
    """根路径接口."""
    return {"message": "欢迎使用信用风险控制系统API"}


@app.get("/health", response_model=HealthResponse)
async def health_check():
    """健康检查接口.
    
    检查项目:
    1. 系统状态
    2. 数据库连接
    3. 系统资源使用情况
    """
    try:
        # 检查数据库连接
        db_healthy = db_manager.check_connection()
        
        # 获取系统信息
        system_healthy, warnings = system_monitor.check_system_health()
        system_info = system_monitor.get_system_info()
        
        # 确定整体状态
        status = "healthy" if (db_healthy and system_healthy) else "unhealthy"
        
        return {
            "status": status,
            "database": db_healthy,
            "system_info": system_info,
            "timestamp": datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"健康检查失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/merchant/{merchant_id}/score", response_model=ScoreResponse)
async def get_merchant_score(merchant_id: str):
    """获取商家信用评分.
    
    Args:
        merchant_id: 商家ID
    """
    try:
        score, dimensions, level, privileges = merchant_scorer.calculate_merchant_score(
            merchant_id
        )
        
        return {
            "score": score,
            "dimension_scores": dimensions,
            "credit_level": level,
            "privileges": privileges,
            "timestamp": datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"获取商家评分失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/user/{user_id}/score", response_model=ScoreResponse)
async def get_user_score(user_id: str):
    """获取用户信用评分.
    
    Args:
        user_id: 用户ID
    """
    try:
        score, dimensions, level, limits = user_scorer.calculate_user_score(user_id)
        
        return {
            "score": score,
            "dimension_scores": dimensions,
            "credit_level": level,
            "privileges": [f"{k}: {v}" for k, v in limits.items()],
            "timestamp": datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"获取用户评分失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/merchant/{merchant_id}/history")
async def get_merchant_score_history(
    merchant_id: str,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None
):
    """获取商家评分历史.
    
    Args:
        merchant_id: 商家ID
        start_date: 开始日期
        end_date: 结束日期
    """
    try:
        history = merchant_scorer.get_merchant_score_history(
            merchant_id,
            start_date,
            end_date
        )
        return history
        
    except Exception as e:
        logger.error(f"获取商家评分历史失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/user/{user_id}/history")
async def get_user_score_history(
    user_id: str,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None
):
    """获取用户评分历史.
    
    Args:
        user_id: 用户ID
        start_date: 开始日期
        end_date: 结束日期
    """
    try:
        history = user_scorer.get_user_score_history(
            user_id,
            start_date,
            end_date
        )
        return history
        
    except Exception as e:
        logger.error(f"获取用户评分历史失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.get(
    "/user/{user_id}/recovery/eligibility",
    response_model=RecoveryEligibilityResponse
)
async def check_credit_recovery_eligibility(user_id: str):
    """检查用户信用恢复资格.
    
    Args:
        user_id: 用户ID
    """
    try:
        is_eligible, status = user_scorer.check_credit_recovery_eligibility(user_id)
        
        return {
            "is_eligible": is_eligible,
            "status": status,
            "timestamp": datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"检查信用恢复资格失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.post(
    "/user/{user_id}/recovery/process",
    response_model=RecoveryProcessResponse
)
async def process_credit_recovery(user_id: str):
    """处理用户信用恢复.
    
    Args:
        user_id: 用户ID
    """
    try:
        success, message, new_level = user_scorer.process_credit_recovery(user_id)
        
        return {
            "success": success,
            "message": message,
            "new_level": new_level,
            "timestamp": datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"处理信用恢复失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.post("/risk/assess", response_model=RiskResponse)
async def assess_transaction_risk(transaction: Dict):
    """评估交易风险.
    
    Args:
        transaction: 交易信息
    """
    try:
        risk_level, risk_score, risk_factors = risk_model.assess_transaction_risk(
            transaction
        )
        
        return {
            "risk_level": risk_level.value,
            "risk_score": risk_score,
            "risk_factors": risk_factors,
            "timestamp": datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"评估交易风险失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.post(
    "/merchant/scores/update",
    response_model=BatchUpdateResponse
)
async def update_merchant_scores(
    batch_size: int = Query(100, description="批处理大小")
):
    """批量更新商家评分.
    
    Args:
        batch_size: 批处理大小
    """
    try:
        processed_count = merchant_scorer.update_merchant_scores(batch_size)
        
        return {
            "success": True,
            "processed_count": processed_count,
            "timestamp": datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"批量更新商家评分失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@app.post(
    "/user/scores/update",
    response_model=BatchUpdateResponse
)
async def update_user_scores(
    batch_size: int = Query(100, description="批处理大小")
):
    """批量更新用户评分.
    
    Args:
        batch_size: 批处理大小
    """
    try:
        processed_count = user_scorer.update_user_scores(batch_size)
        
        return {
            "success": True,
            "processed_count": processed_count,
            "timestamp": datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"批量更新用户评分失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)